import Icon from '@/components/Icon'
import { NavBar, Input } from 'antd-mobile'
import { useHistory } from 'react-router-dom'
import styles from './index.module.scss'
import { useState, useEffect, useRef } from 'react'
import { useInitState } from '@/utils/hooks'
import { getUser } from '@/store/actions/profile'
import { getToken } from '@/utils/storage'
import io, { Socket } from 'socket.io-client'

const Chat = () => {
  const history = useHistory()

  const [messageList, setMessageList] = useState<
    {
      type: 'robot' | 'user',
      text: string
    }[]
  >([
    { type: 'robot', text: '亲爱的用户您好，小智同学为您服务。' },
    { type: 'user', text: '你好' }
  ])

  // 当前用户信息
  const { user } = useInitState(getUser, 'profile')
  const socketRef = useRef<Socket | null>(null)
  // 输入框中的内容
  const [message, setMessage] = useState('')
  // 用于操作聊天列表元素的引用
  const listRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    // 创建客户端实例
    const socket = io('http://geek.itheima.net', {
      query: {
        token: 'Bearer ' + getToken().token
      },
      transports: ['websocket']
    })

    // 将客户端实例缓存到 ref 引用中
    socketRef.current = socket

    // 监听连接成功的事件
    socket.on('connect', () => {
      setMessageList((list) => [
        ...list,
        {
          type: 'robot',
          text: '我现在恭候着您的提问.'
        }
      ])
    })

    // 监听收到消息的事件
    socket.on('message', (data) => {
      // 向聊天记录中添加机器人回复的消息
      setMessageList((messageList) => [
        ...messageList,
        { type: 'robot', text: data.msg },
      ])
    })


    return () => {
      socket.close()
    }
  }, [])

  // 发消息
  const onSendMessage = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.keyCode === 13) {
      // 通过 socket.io 客户端向服务端发送消息
      socketRef.current?.emit('message', {
        msg: message,
        timestamp: Date.now()
      })

      // 向聊天记录中添加当前发送的消息
      setMessageList(messageList => [
        ...messageList,
        { type: 'user', text: message }
      ])

      // 发送后清空输入框
      setMessage('')
    }
  }

  // 监听聊天数据的变化，改变聊天容器元素的 scrollTop 值让页面滚到最底部
  useEffect(() => {
    const current = listRef.current!
    current.scrollTop = current.scrollHeight
  }, [messageList])

  return (
    <div className={styles.root}>
      {/* 顶部导航栏 */}
      <NavBar className="fixed-header" onBack={() => history.go(-1)}>
        小智同学
      </NavBar>

      {/* 聊天记录列表 */}
      <div className="chat-list" ref={listRef}>
        {messageList.map((item, index) => {
          return item.type === 'robot' ? (
            <div className="chat-item" key={index}>
              <Icon type="iconbtn_xiaozhitongxue" />
              <div className="message">{item.text}</div>
            </div>
          ) : (
            <div className="chat-item user" key={index}>
              <img src={user.photo} alt="" />
              <div className="message">{item.text}</div>
            </div>
          )
        })}
      </div>

      {/* 底部消息输入框 */}
      <div className="input-footer">
        <Input
          className="no-border"
          placeholder="请描述您的问题"
          value={message}
          onChange={e => setMessage(e)}
          onKeyUp={onSendMessage} />
        <Icon type="iconbianji" />
      </div>
    </div>
  )
}

export default Chat
